package com.ahnchan.ContactsPlus;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ahnchan.ContactsPlus.R;
import com.ahnchan.ContactsPlus.util.WordUtils;
import com.ahnchan.ContactsPlus.util.ListUtils;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnKeyListener;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Contacts;
import android.provider.ContactsContract;
import android.provider.Contacts.Groups;
import android.provider.Contacts.People;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.CommonDataKinds.Organization;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.SectionIndexer;
import android.widget.SeekBar;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;

/**
 * Contacts tab activity
 * 
 * @author Ahnchan
 *
 */
public class ContactsActivity extends ListActivity {

	private ContactsPlusSetting setting;	// Properties
	private boolean bSearchFocus = false; // Search textedit focus control
	
	private ContactsAdapter mContactsAdapter;
	
	private ArrayList<Contact> aList;
	private ArrayList<Contact> aOrgList;	// Backup (All Contacts, sorted)
	
	public static final String TEXT_TYPE = "TYPE";
	public static final String TEXT_MEMBER = "MEMBER";	// input data type
	public static final String TEXT_GROUP = "GROUP";
	public static final String TEXT_DATA = "DATA";
	public static final String TEXT_TITLE = "TITLE";

	private String strFlag;
	private String strData;
	private String strTitle;
	
	private int iSelection = 0;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {

    	super.onCreate(savedInstanceState);
        setContentView(R.layout.contact_list);
        
        setting = ContactsPlusSetting.instatnce();
        this.getListView().setBackgroundColor(setting.getFontBGColor());	// Set list background color 

        strFlag = getIntent().getStringExtra(TEXT_TYPE);
        strData = getIntent().getStringExtra(TEXT_DATA);
        if (null != strFlag) {
        	setting.setContactsPosition(0);
        	
        	Log.d("ContactsPlus", "[ContactsActivity] strFlag:"+strFlag+",strData:"+strData);
        }

        // Commented by Ahnchan. 2011.1.2
        // New Method~! Customize Adapter class and change initialize position. 
        // List Setting
//      mAdapter = new SimpleAdapter(this, aList, R.layout.contact_list_row,
//        							new String[] {"NAME"}, 
//        							new int[] {R.id.name_text});
//      setListAdapter(mAdapter);
        // Customized Adapter
        // remark by Ahnchan 2011.2
//        mContactsAdapter = new ContactsAdapter();
//        setListAdapter(mContactsAdapter);

        // Click in Contacts list
        ListView lv = getListView();
        lv.setTextFilterEnabled(true);

        lv.setOnItemClickListener(new OnItemClickListener() {
        	/**
        	 * Show contact info
        	 */
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
				
				setting.setContactsPosition(arg2);
				
				Contact contact = aList.get(arg2);
				viewContact(contact);
			}
        });
        
        // Long click Event
        lv.setOnItemLongClickListener(new OnItemLongClickListener() {

			public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
				Contact contact = aList.get(arg2);

				setting.setContactsPosition(arg2);

				viewLongContact(contact);
				
				return false;
			}
        	
        });

        // Add button event
        ImageButton addButton = (ImageButton)findViewById(R.id.add_button);
        addButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				addContact();
			}
        });

        // Search edit text event
        EditText searchEdit = (EditText)findViewById(R.id.contact_search_edit);
//        searchEdit.setFocusable(false);
//        searchEdit.clearFocus();
        searchEdit.addTextChangedListener(new TextWatcher() 
        {
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub
			}

			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub
			}

			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				searchContact();
			}
        });
        searchEdit.setOnClickListener(new View.OnClickListener() 
        {
			public void onClick(View v) {
				// Found soft key hidden method 
				// Ahnchan 20110215
				// add manifest -> windowSoftInputMode 
//		    	if (!bSearchFocus) {
//			        changeSearchEditFocus();
//		    	}
			}
		});
        
        // Show search option - Ahnchan 20110610
        if (!setting.getShowSearch()) {
        	// Hide search tab
        	LinearLayout search = (LinearLayout)findViewById(R.id.contacts_search_section);
        	search.setLayoutParams(new LinearLayout.LayoutParams(0,0));
        }

        // Get contact list
//        showContactList();
    }
    
    protected void onResume() {
    	super.onResume();
    	
    	EditText edit = (EditText)findViewById(R.id.contact_search_edit);
		String strSearch = edit.getText().toString();

		if ("".equals(strSearch) || null == strSearch) {
			showContactList();
		} else {
			searchContact();
		}
    	
    	// move last click contacts
    	ListView lv = getListView();
    	lv.setSelection(setting.getContactsPosition());
    }

    /**
     * Change search edit forcusable
     */
    public void changeSearchEditFocus() {
    	
    	EditText searchEdit = (EditText)findViewById(R.id.contact_search_edit);
		searchEdit.setCursorVisible(true);
		searchEdit.setFocusableInTouchMode(true);
		searchEdit.setFocusable(true);
   	
    	InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
	    imm.showSoftInput(searchEdit, InputMethodManager.SHOW_IMPLICIT);

	    bSearchFocus = true;
	    
    }
    
    /**
     * Custom Simple Adapter Class
     * Change Font size, control contacts photo size
     * Bind Image
     */
    class ContactsAdapter extends BaseAdapter implements SectionIndexer {

    	
    	private Context context;
    	private ArrayList<Contact> conList;
    	
		/**
    	 * Constructor
    	 */
		public ContactsAdapter(Context _context, ArrayList<Contact> list) {
			context = _context;
			conList = list;
		}
		
		public int getCount() {
			return conList.size();
		}
		
		public Object getItem(int position) {
			return conList.get(position);
		}
		
		/**
		 * Bind information
		 */
		public View getView(int position, View convertView, ViewGroup parent) {
			
			// No photo.
			int iRowID = R.layout.contact_list_no_pic_row;
			
			if (setting.getIntFontSize() < 15) {
				iRowID = R.layout.contact_list_no_pic_row;
			}
			
			LayoutInflater inflater = getLayoutInflater();
			View row = inflater.inflate(iRowID, parent, false);
			
			// Header
			LinearLayout header = (LinearLayout)row.findViewById(R.id.contact_section);
			
			// set text
			Contact contact = conList.get(position);
			String strLabel = contact.getName();
			String strDisplayLabel = contact.getDisplayName();
			
			if (setting.getContactIndex()) {
				char firstChar = WordUtils.getFirstInitial(strLabel.toUpperCase(), 
															setting.getTypeSymbolNumber(),
															setting.getSpreadSymbol(),
															setting.getSpreadNumber());
				if (position == 0) {
					setSection(header, ""+firstChar);
				} else {
					String strPreLabel = conList.get(position-1).getName();
					char preFirstChar = WordUtils.getFirstInitial(strPreLabel.toUpperCase(), 
																	setting.getTypeSymbolNumber(),
																	setting.getSpreadSymbol(),
																	setting.getSpreadNumber());
					if (firstChar != preFirstChar) {
						setSection(header, ""+firstChar);
					} else {
						header.setVisibility(View.GONE);
					}
				}
			} else {
				header.setVisibility(View.GONE);
			}
			
			TextView label = (TextView) row.findViewById(R.id.name_text);
			label.setTextSize(setting.getIntFontSize());
			label.setText(strDisplayLabel);
			label.setTextColor(setting.getFontColor());
			label.setBackgroundColor(setting.getFontBGColor());
						
			// Image bind
			if (iRowID == R.layout.contact_list_row) {
				
				// Get Bitmap
				
				// Set image

			}
			
			return row;
		}
		
		public void setSection(LinearLayout header, String firstChar) {
			
			TextView text = new TextView(context);
			header.setBackgroundColor(setting.getIndexTitleBGColor());
			text.setTextColor(setting.getIndexTitleColor());
			
			if ("0".equals(firstChar) && !setting.getSpreadNumber()) {
				firstChar = "0~9";
			}
			
			text.setText(firstChar);
			text.setTextSize(setting.getIndexFontSize());
			text.setPadding(5, 0, 0, 0);
			text.setGravity(Gravity.CENTER_VERTICAL);
			header.addView(text);			
		}

		public long getItemId(int arg0) {
			return 0;
		}

		public int getPositionForSection(int section) {
			if (section == 35) {
				return 0;
			}
			for(int i=0; i<conList.size(); i++) {
				Contact l = conList.get(i);
				char firstChar = l.getName().toUpperCase().charAt(0);
				if(firstChar == section) {
					return i;
				}
			}
			return -1;
		}

		public int getSectionForPosition(int arg0) {
			return 0;
		}

		public Object[] getSections() {
			return null;
		}
    }

    /**
     * View contact info
     * @param contact	Contact class
     */
    private void viewContact(Contact contact) {
    	
    	String strContactID = contact.getID();

    	// Comment by ahnchan 20110210
    	// change Contact URI method
//    	Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("content://contacts/people/"+strContactID));
//    	startActivity(intent);  
    	
    	Intent intent = new Intent(Intent.ACTION_VIEW);
        Uri ui = ContactsContract.Contacts.CONTENT_URI;
        intent.setData(Uri.parse(ui+"/"+strContactID));
        startActivity(intent);
        
	}

    /**
     * Contact Detail Dialog
     * @param contact
     */
    private void viewLongContact(Contact contact) {

    	String strContactID = contact.getID();
    	String strContactName = contact.getName();
    	
    	Intent contactIntent = new Intent(this, ContactsDetailActivity.class);
    	contactIntent.putExtra(ContactsDetailActivity.ID_DATA, strContactID);
    	contactIntent.putExtra(ContactsDetailActivity.NAME_DATA, strContactName);
//    	startActivityForResult(contactIntent, 1);
    	
    	startActivity(contactIntent);
    }
    
    /**
     * Add contact event
     */
    public void addContact() {
//    	Intent intent = new Intent(Intent.ACTION_INSERT, Uri.parse("content://contacts/people"));
    	
    	Intent intent = new Intent(Intent.ACTION_INSERT);
    	intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
    	
    	startActivity(intent);
	}
    
    /**
     * Search contact. 
     * Name, Initial, E-Mail, Phone, Memo 
     */
    public void searchContact() {

    	// old type
    	// search in db
//    	EditText edit = (EditText)findViewById(R.id.contact_search_edit);
//		showContactList(edit.getText().toString());

    	// Check 
    	if (null == aOrgList) return;
    	if (aOrgList.size() <= 0) return;
    	
    	// initialize list array
    	aList = new ArrayList<Contact>();

    	EditText edit = (EditText)findViewById(R.id.contact_search_edit);
		String strSearch = edit.getText().toString();
		
		//--------------------------------------------------
		// Search Initial
		//--------------------------------------------------
    	for(int i=0; i < aOrgList.size(); i++) {
    		Contact con = aOrgList.get(i);
    		if (con.isThis(strSearch)) {
    			aList.add(con);
    		}
    	}
    	
    	//--------------------------------------------------
    	// Search Note, EMail, Phone
    	//--------------------------------------------------
    	strSearch = WordUtils.checkSearchWord(strSearch);
    	ArrayList<Contact> searchList = searchContactList(strSearch);
    	

    	aOrgList = ListUtils.setShowAll(aOrgList, false, "Contact");
    	aList = ListUtils.mergeList(aOrgList, aList, searchList, "Contact");


    	mContactsAdapter = new ContactsAdapter(this, aList);
    	setListAdapter(mContactsAdapter);
    }

    /**
     * Search
     * Memo, Phone, E-Mail
     * 
     * @param data
     * @return
     */
    private ArrayList<Contact> searchContactList(String data) {

    	ArrayList<Contact> resultList = new ArrayList<Contact>();
    	
    	String[] projection_data = new String[] {
    			ContactsContract.Data.CONTACT_ID,
    			ContactsContract.Data.DISPLAY_NAME,
	    		ContactsContract.Data.DATA1
    	};
		
		String selection = "(" + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE + "'"
						+ " OR " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'"
						+ " OR " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE + "'"
						+ " OR " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE + "'"
						+ " OR " + ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE + "')"
						+ " AND " + ContactsContract.Data.DATA1 + " like '%" + data + "%'";
//		String selection = ContactsContract.Data.DATA1 + " like '%" + data + "%'";
		
		String order = ContactsContract.Data.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
		
		Cursor mCursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, 
													projection_data, selection, null, order);
		
		if (mCursor == null) {
			return resultList;
		}
		
		if (mCursor.moveToFirst()) {
			do {
				Contact contact = new Contact(mCursor.getString(0), 
											null, 
											mCursor.getString(1),
											mCursor.getString(1), 
											0, "", mCursor.getString(1));

				resultList.add(contact);
				
			} while (mCursor.moveToNext());
		}
		
		mCursor.close();
		
		return resultList;
    }
    
    private void showContactList() {
    	showContactList("");
    }
    
    /**
     * Get contact information
     */
    private void showContactList(String search) {
    	
	    // Initialization list	
    	aList = new ArrayList<Contact>();

    	// where
    	String[] projection_data;
    	
    	// select
    	String selection = "" ;
    	
    	// Order by
    	String order = "";
    	
    	// Cursor
    	Cursor mCursor;

    	// to check performance
    	Long startTime = System.currentTimeMillis();
    	
    	if (null != strFlag) {

    		projection_data = new String[] {
        			ContactsContract.Data.CONTACT_ID,
        			ContactsContract.Data.DISPLAY_NAME,
        			ContactsContract.Data.DATA1,	// 2 DISPLAY_NAME
        			ContactsContract.Data.DATA2,	// 3 First name
        			ContactsContract.Data.DATA3,	// 4 Last name
        			ContactsContract.Data.DATA4,	// 5 Prefix (Mr. Miss. ...)
        			ContactsContract.Data.DATA5,	// 6 Middle name
        			ContactsContract.Data.DATA6,	// 7 Suffix (Jr Sr )
        			ContactsContract.Data.MIMETYPE
        	};
    		
    		selection = ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'";

    		//---------------
    		// Member search 
    		//---------------
    		if (strFlag.equals(TEXT_MEMBER)) {

    			// Search Company member
    			
    			selection += " AND " + ContactsContract.Data.CONTACT_ID + " in (" + strData + ")";
    			
    		} else if (strFlag.equals(TEXT_GROUP)) {
    			
    			// Search Group member
    			
    			// Get group member 
    			Cursor mGroupCursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, 
						new String[]{ContactsContract.Data.CONTACT_ID}, 
						ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE + "' " 
		    			+ " AND " + Data.DATA1 + "='" + strData + "'", null, "");

    			String strGroupID = "";
    			if (mGroupCursor.moveToFirst()) {
    	    		do {
    	    			strGroupID += "'" + mGroupCursor.getString(0) + "'";
    	    			
    	    			if (!mGroupCursor.isLast()) {
    	    				strGroupID += ",";
    	    			}
    	    		} while (mGroupCursor.moveToNext());
    			}
    			mGroupCursor.close();
    			
    			selection += " AND " + ContactsContract.Data.CONTACT_ID + " IN (" + strGroupID + ")";
    			
    		}

        	// Search
    		// Remark by Ahnchan 20110119
    		// Change search method. initial search, not db query
//        	if ((null != search) && (search.length()>0)) {
//        		selection += " AND " + ContactsContract.Data.DISPLAY_NAME + " like '%" + search + "%'";
//        		setText(selection);
//        	}
//        	order = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
//        	mCursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, 
//					projection_data, selection, null, order);

    		if (setting.getSortLastname()) {
        		order = ContactsContract.Data.DATA3 + " COLLATE LOCALIZED ASC";
        	} else {
        		order = ContactsContract.Data.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
        	}

        	mCursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, 
        										projection_data, selection, null, order);

    	} else {
    		
    		//---------------
    		// Contact list
    		//---------------
/*
// by ahnchan 20110426
     		projection_data = new String[] {
        			ContactsContract.Contacts._ID,
        			ContactsContract.Contacts.DISPLAY_NAME,
        			ContactsContract.Contacts.PHOTO_ID,
        			ContactsContract.Contacts.TIMES_CONTACTED,
        			ContactsContract.Contacts.LAST_TIME_CONTACTED,
        			ContactsContract.Contacts.STARRED,
        			ContactsContract.Contacts.CONTACT_PRESENCE,
        			ContactsContract.Contacts.CONTACT_STATUS,
        			ContactsContract.Contacts.CONTACT_STATUS_TIMESTAMP,
        			ContactsContract.Contacts.CONTACT_STATUS_LABEL,
        			ContactsContract.Contacts.CONTACT_STATUS_ICON,
        	};
    		
        	order = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
        	
        	mCursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, 
        										projection_data, selection, null, order);
 */   		

    		Log.d("ContactsPlus", "Start all contacts.");
    		
    		projection_data = new String[] {
        			ContactsContract.Data.CONTACT_ID,
        			ContactsContract.Data.DISPLAY_NAME,
        			ContactsContract.Data.DATA1,	// 2 DISPLAY_NAME
        			ContactsContract.Data.DATA2,	// 3 First name
        			ContactsContract.Data.DATA3,	// 4 Last name
        			ContactsContract.Data.DATA4,	// 5 Prefix (Mr. Miss. ...)
        			ContactsContract.Data.DATA5,	// 6 Middle name
        			ContactsContract.Data.DATA6 ,		// 7 Suffix (Jr Sr )
        			ContactsContract.Data.MIMETYPE
//        			ContactsContract.Contacts.HAS_PHONE_NUMBER,	// Phone number
//        			ContactsContract.Contacts.PHOTO_ID	// Photo_id
        	};
    		
    		selection = ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'";
        	
        	if (setting.getSortLastname()) {
        		order = ContactsContract.Data.DATA3 + " COLLATE LOCALIZED ASC";
        	} else {
        		order = ContactsContract.Data.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
        	}
        	
        	mCursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, 
        										projection_data, selection, null, order);
    	}

    	if (mCursor == null) {
    		return;
    	}
    	
    	int iTotal = 0;
    	int iSkip = 0;
    	
    	if (mCursor.moveToFirst()) {
    		
    		String strOrgID = "";
    		
    		do {

    			String strID = mCursor.getString(0);
    			String strName = "";
    			String strDisplayName = "";
    			
    			// Skip duplicate contact info
    			if (strOrgID.equals(strID)) {
//    				Log.e("ContactsPlus", "Duplicate:"+strID +":"+ mCursor.getString(1));
    				iSkip++;
    				continue;
    			}    			

    			// Display last name first
				if (setting.getDisplayLastname()) {
					if (ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE.equals(mCursor.getString(8))) {
						strDisplayName = (null == mCursor.getString(4) ? "" : mCursor.getString(4).trim()) 
							 + ("".equals(mCursor.getString(6)) || null == mCursor.getString(6) ? "" : " " + mCursor.getString(6).trim())
							 + ("".equals(mCursor.getString(3)) || null == mCursor.getString(3) ? "" : " " + mCursor.getString(3).trim())
							 + ("".equals(mCursor.getString(7)) || null == mCursor.getString(7) ? "" : " " + mCursor.getString(7).trim());
					} else {
						strDisplayName = mCursor.getString(1);
					}
				} else {
					strDisplayName = mCursor.getString(1);
				}
				
				// Sort by last name
				if (setting.getSortLastname()) {
					if (ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE.equals(mCursor.getString(8))) {
						strName = (null == mCursor.getString(4) ? "" : mCursor.getString(4).trim()) 
								+ ("".equals(mCursor.getString(6)) || null == mCursor.getString(6) ? "" : " " + mCursor.getString(6).trim())
								+ ("".equals(mCursor.getString(3)) || null == mCursor.getString(3) ? "" : " " + mCursor.getString(3).trim())
								+ ("".equals(mCursor.getString(7)) || null == mCursor.getString(7) ? "" : " " + mCursor.getString(7).trim());
					} else {
						strName = mCursor.getString(1);
					}
				} else {
					strName = mCursor.getString(1);
				}
				
				if (null != strName) strName = strName.trim();
				if (null != strDisplayName) strDisplayName = strDisplayName.trim();
				
    			// Search
    			// Initial search (ex. Claude Ahn --> Search of "CA")
    			// Korean searched same method. called "ChoSung search"
    			// Remark by Ahnchan 20110119 Speed issue. it's too slow.
//            	if ((null != search) && (search.length()>0)) {
//            		if (WordUtils.isInitialSound(strName, search) || 
//            		    WordUtils.isHangulInitialSound(strName, search) ||
//            			(strName.toUpperCase().indexOf(search.toUpperCase()) >= 0)) {
//            			// Find~~!
//            		} else {
//            			continue;            			
//            		}
//            	}

//				Log.d("ContactsPlus", ""+iTotal+":"+strID+":"+strDisplayName);

/*
// Performance Issue (2011/5/3)

    			// Get Photo_id, Has_phone_number...
            	Cursor mDataCursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, 
            						new String[]{ContactsContract.Contacts.PHOTO_ID, 
            									 ContactsContract.Contacts.HAS_PHONE_NUMBER}, 
            						ContactsContract.Contacts._ID + "=" + strID, null, "");
            	
            	String strHasPhoneNumber = "";
            	
            	if (mDataCursor.moveToFirst()) {
            		
            		// Display only phone number
            		strHasPhoneNumber = mDataCursor.getString(1);
            	}
    			mDataCursor.close();

    			// Check display only phone number
        		if (setting.getOnlyPhone() && "0".equals(strHasPhoneNumber)) {
        			continue;
        		}
*/
				
    			// Create object
    			Contact contact = new Contact(strID, 
    										null, 
    										strName,
    										strDisplayName,
    										0, "", strName);
  
    			aList.add(contact);
    			
//    			Log.d("ContactsPlus", "[ContactsActivity]"+contact.getID()+","+contact.getContactID()+","+contact.getName());
    			
    			iTotal++;
				
				strOrgID = strID;
    	
    		} while (mCursor.moveToNext());
    		
    		
    		// Debug Info
    		setText("Count:" + iTotal);
    	}
    	
    	// Sorting list
    	aList = ListUtils.sortList(aList, setting.getTypeList(), setting.getLocalLanguage(), "Contact");
    	
    	aOrgList = aList;	// to list search, saved all data
    	int iDBTotal = mCursor.getCount();
    	mCursor.close();
    	
		// Debug (Performance Test)
		Long endTime = System.currentTimeMillis();    		
		
		Log.d("ContactsPlus", "[ContactsActivity] Diff : " + (endTime - startTime) +" msec");
		Log.d("ContactsPlus", "[ContactsActivity] Count : " + iTotal +", Skip : " + iSkip + ", DB Count : " + iDBTotal);
		Log.d("ContactsPlus", "[ContactsActivity] List : " + aList.size());

		// Debug
//    	backupContact();
//    	debugContact();
//    	debugData();
    	
    	mContactsAdapter = new ContactsAdapter(this, aList);
    	setListAdapter(mContactsAdapter);

    	return;
    }

    /**
     * DEBUG
     */
    private void debugData() {

    	Log.e("ContactsPlus", "[ContactsActivity] Debug session start =======");
    	
    	
    	// TEST only company name
		String[] projection_data = new String[] {
    			ContactsContract.Data.CONTACT_ID,
    			ContactsContract.Data.DISPLAY_NAME,
    			ContactsContract.Data.MIMETYPE,
    			ContactsContract.Data.DATA1,	// 2 DISPLAY_NAME
    			ContactsContract.Data.DATA2,	// 3 First name
    			ContactsContract.Data.DATA3,	// 4 Last name
    			ContactsContract.Data.DATA4,	// 5 Prefix (Mr. Miss. ...)
    			ContactsContract.Data.DATA5,	// 6 Middle name
    			ContactsContract.Data.DATA6		// 7 Suffix (Jr Sr )
    	};
//		String selection = ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'";
//		selection += " AND " + ContactsContract.Data.CONTACT_ID + " in ('1072', '113')";
		
		String selection = ContactsContract.Data.CONTACT_ID + " in ('1072', '113')";
		
		String order = "";

		Cursor mCursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, 
    										projection_data, selection, null, order);

    	
		Log.e("ContactsPlus", "[ContactsActivity]"+mCursor.toString());
    	
    	if (mCursor == null) {
    		Log.e("ContactsPlus", "[ContactsActivity] Cursor is null.");
			return;
		}
		
		if (mCursor.moveToFirst()) {
			String strData = "";
			do {
				strData = mCursor.getString(0) + "," + mCursor.getString(1) + "," + mCursor.getString(2);
				
				Log.e("ContactsPlus", "[ContactsActivity] : " + strData);
			} while (mCursor.moveToNext());
		}
		
		mCursor.close();
    	
    	Log.e("ContactsPlus", "[ContactsActivity] Debug session end =======");
    }
    
    private Contact setContactNote(Contact contact, String strID) {
    	
    	String[] projection_data = new String[] {
    			ContactsContract.Data._ID,
	    		ContactsContract.Data.DATA1,
	    		ContactsContract.Data.DATA2,
	    		ContactsContract.Data.DATA3
    	};
		
		String selection = ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE + "'" + 
						   " AND " + ContactsContract.Contacts._ID + "=" + strID;
    	String order = "";
    	
    	Cursor mCursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, 
    										projection_data, selection, null, order);
			
//		Cursor mCursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, 
//				new String[]{ContactsContract.Data.DATA1}, 
//				ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE + "' " 
//    			+ " AND " + ContactsContract.Data._ID + "=" + strID, null, "");

    	
    	if (mCursor == null) {
			return contact;
		}
		
		String strNote = "";
		
		if (mCursor.moveToFirst()) {
			
			do {
				
				strNote += mCursor.getString(1);
		
			} while (mCursor.moveToNext());

		}
		
//		contact.setNote(strNote);
		
		mCursor.close();

		return contact;
    }

    
    /**
     * Backup data (TEXT file)
     */
    private void backupContact() {
//    	String sdcardPath = Environment.getDownloadCacheDirectory().getAbsolutePath();
//    	String root = Environment.getExternalStorageState();
    	File root = Environment.getExternalStorageDirectory();
//    	File file = new File(root, "ContactsPlus_Backup");
    	
    	setText(root.getAbsolutePath());
    	
    	try {
//    		file.createNewFile();
//    		FileOutputStream fos = new FileOutputStream(file.getAbsolutePath());
//    		String text = "";
    		
			File data = new File(root, "ContactsPlus.txt");
			FileWriter writer = new FileWriter(data);
			BufferedWriter out = new BufferedWriter(writer);
			    			
			for(int i=0; i<aOrgList.size(); i++) {
            	Contact contact = aOrgList.get(i);
            	writer.append(contact.getName() + "\n");            	
        	}
		
			out.close();
    	} catch (IOException ie) {
    		Log.e("ContactsActivity", ie.toString());
    	}
    }
    
    /**
     * 
     * @param cr
     * @param id
     * @return
     */
    public static Bitmap getContactPhoto(ContentResolver cr, long  id) {
        Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
        InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
        if (input == null) {
            return null;
        }
        return BitmapFactory.decodeStream(input);
    }

    
	/**
	 * Debug Text view
	 * @param message
	 */
    private void setText(String message) {
    	TextView text = (TextView)findViewById(R.id.contact_list_text);
    	text.setText(message);
    }
	
    /**
     * create option Menu
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	
    	MenuInflater inflater = getMenuInflater();
    	inflater.inflate(R.menu.option_menu, menu);
    	
    	return true;
    }
    
    /**
     * Option menu action
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	
    	switch (item.getItemId()) {
    	case R.id.option_setting :
    		
    		Intent settingIntent = new Intent(this, SettingActivity.class);
    		startActivity(settingIntent);
    		return true;
    		
    	case R.id.option_about :

    		Intent aboutIntent = new Intent(this, AboutActivity.class);
    		startActivity(aboutIntent);
    		return true;
    		
    	case R.id.option_refresh :

    		// Clear search word 
        	EditText edit = (EditText)findViewById(R.id.contact_search_edit);
        	edit.setText("");

        	// Reload data
    		showContactList();
    		
    		return true;
    	
    	case R.id.option_fontsize :
    		
    		FontSizeDialog fontDialog = new FontSizeDialog(this, this, FontSizeDialog.CONTACTS);
    		fontDialog.show();
    		
    		return true;
    		
    	case R.id.option_color :
    		
    		ColorDialog colorDialog = new ColorDialog(this, this, ColorDialog.CONTACTS);
    		colorDialog.show();
    		
    		return true;
    	}
    	return false;
    }
    
    /**
     * Change list font size
     * @param fontSize
     */
    public void changeFontSize(int fontSize) {
    	setting.setFontSize(""+fontSize);
    	
    	mContactsAdapter = new ContactsAdapter(this, aList);
    	setListAdapter(mContactsAdapter);    	
    }

    /**
     * Change list index font size
     * @param fontSize
     */
    public void changeIndexFontSize(int fontSize) {
    	setting.setIndexFontSize(""+fontSize);
    	
    	mContactsAdapter = new ContactsAdapter(this, aList);
    	setListAdapter(mContactsAdapter);    	
    }

    /**
     * Change list font Color
     * @param color
     */
    public void changeFontColor(int color) {
    	setting.setFontColor(color);
    	
    	mContactsAdapter = new ContactsAdapter(this, aList);
    	setListAdapter(mContactsAdapter);    	
    }

    public void changeFontBGColor(int color) {
    	setting.setFontBGColor(color);
    	
    	this.getListView().setBackgroundColor(color);
    	mContactsAdapter = new ContactsAdapter(this, aList);
    	setListAdapter(mContactsAdapter); 
    }
    

    /**
     * Change list index color
     * @param color
     */
    public void changeIndexFontColor(int color) {
    	setting.setIndexTitleColor(color);
    	
    	mContactsAdapter = new ContactsAdapter(this, aList);
    	setListAdapter(mContactsAdapter);    	
    }

    public void changeIndexFontBGColor(int color) {
    	setting.setIndexTitleBGColor(color);
    	
    	mContactsAdapter = new ContactsAdapter(this, aList);
    	setListAdapter(mContactsAdapter);    	
    }
}